package top.boycharse.ftp.server.common;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;

public class DataDTP {

    private String IP;

    private int port;

    public DataDTP(String IP, int port) {
        this.IP = IP;
        this.port = port;
    }

    private void connect(String host, int port, Strategy strategy) {
        ThreadPoolManager.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                Socket socket = null;
                OutputStream outputStream = null;
                InputStream inputStream = null;
                try {
                    socket = new Socket(host,port);
                    if (strategy != null) {
                        outputStream = socket.getOutputStream();
                        inputStream = socket.getInputStream();
                        strategy.op(outputStream,inputStream);
                    }
                }catch (Exception e) {
                    if (strategy != null) {
                        strategy.exception(e);
                    }
                }finally {
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
    }

    public void returnFileNames(String[] fileNames) {
        connect(IP, port, new Strategy() {
            @Override
            public void op(OutputStream outputStream, InputStream inputStream) {
                DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

                try {
                    for (String temp:fileNames) {
                        dataOutputStream.writeBytes(temp + "\n");
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void exception(Exception e) {

            }
        });
    }

    public void waitDownload(String pathname, DownLoadListener listener) {
        connect(IP, port, new Strategy() {
            @Override
            public void op(OutputStream outputStream, InputStream inputStream) {
                if (listener != null) {
                    listener.open();
                }
                File file = new File(pathname);
                FileInputStream fileInputStream = null;
                try {
                    fileInputStream = new FileInputStream(file);
                    byte[] b = new byte[1024];
                    int len = -1;
                    while ((len = fileInputStream.read(b)) != -1) {
                        outputStream.write(b,0,len);
                    }
                    fileInputStream.close();
                    outputStream.flush();
                    outputStream.close();
                    if (listener != null) {
                        listener.onSuccess();
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    try {
                        fileInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void exception(Exception e) {

            }
        });
    }

    public void upload(String pathname,UpLoadListener listener) {
        connect(IP, port, new Strategy() {
            @Override
            public void op(OutputStream outputStream, InputStream inputStream) {
                FileOutputStream fileOutputStream = null;
                try {
                    File file = new File(pathname);
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    fileOutputStream = new FileOutputStream(file);
                    byte[] b = new byte[1024];
                    int len = -1;
                    while ((len = inputStream.read(b)) != -1) {
                        fileOutputStream.write(b,0,len);
                    }
                    fileOutputStream.flush();
                }catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    if (fileOutputStream != null) {
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }

            @Override
            public void exception(Exception e) {

            }
        });
    }

    public void append(String pathname,UpLoadListener listener) {
        connect(IP, port, new Strategy() {
            @Override
            public void op(OutputStream outputStream, InputStream inputStream) {
                FileOutputStream fileOutputStream = null;
                try {
                    File file = new File(pathname);
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    fileOutputStream = new FileOutputStream(file,true);
                    byte[] b = new byte[1024];
                    int len = -1;
                    while ((len = inputStream.read(b)) != -1) {
                        fileOutputStream.write(b,0,len);
                    }
                    fileOutputStream.flush();
                }catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    if (fileOutputStream != null) {
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }

            @Override
            public void exception(Exception e) {

            }
        });
    }

    public interface Strategy {
        void op(OutputStream outputStream,InputStream inputStream);

        void exception(Exception e);
    }

    public interface DownLoadListener{
        void onSuccess();

        void onException();

        void open();
    }

    public interface UpLoadListener{
        void onSuccess();

        void onException();
    }
}
